<?php

/**
 *  邮件服务类
 */

namespace app\api\service;

use PHPMailer\PHPMailer\PHPMailer;
use think\facade\Config;
use think\facade\Log;


class MailService
{
    public static function sendMail($to, $subject, $content)
    {

        $mail = new PHPMailer();
        $config = Config::get('mail');
        $mail->isSMTP(); // 使用SMTP服务发送邮件
        $mail->SMTPAuth = true; // 启用 SMTP 认证
        $mail->Host = $config['host']; // SMTP 服务器
        $mail->Port = $config['port']; // SMTP服务器的端口号
        $mail->Username = $config['username']; // SMTP账号
        $mail->Password = $config['password']; // SMTP密码

        $mail->From = $config['mail_from']; // 发件人邮箱
        $mail->FromName = $config['name_from']; // 发件人名称
        $mail->isHTML(true); // 邮件正文是否为html编码
        $mail->CharSet = 'utf-8'; // 设置邮件字符集
        $mail->addAddress($to); // 收件人邮箱地址
        $mail->Subject = $subject; // 邮件标题
        $mail->Body = $content; // 邮件内容


        if (!$mail->send()) {
            return $mail->ErrorInfo;
        } else {
            return true;
        }
    }

    public static function sendEmailTemplate($params)
    {
        // 参数有效性验证
        if (
            !isset($params['to']) ||
            !isset($params['subject']) ||
            !isset($params['template_id']) ||
            empty($params['to']) ||
            empty($params['subject']) ||
            empty($params['template_id'])
        ) {
            return ['status' => false, 'error' => 'Invalid parameters'];
        }
        // 构建模板文件路径
        $templatePath = public_path('template');
        $templateFile = $templatePath . $params['template_id'] . '.html';

        // 验证模板文件存在性
        if (!file_exists($templateFile)) {
            return ['status' => false, 'error' => 'Template not found'];
        }

        // 读取模板内容
        $templateContent = file_get_contents($templateFile);
        if ($templateContent === false) {
            return ['status' => false, 'error' => 'Failed to read template'];
        }
        // 获取动态数据
        $templateData = self::fetchTemplateData($params['template_id'], $params);
        if ($templateData === false) {
            return ['status' => false, 'error' => 'Data fetching failed'];
        }

        //替换模板变量
        $emailBody = self::renderTemplate($templateContent, $templateData);
      
        //发送邮件
        $result = self::sendMail($params['to'], $params['subject'], $emailBody);
        if (!$result) {
            return ['status' => false, 'error' => 'Data send failed'];
        }
        return ['status' => true, 'error' => ''];
    }

    private static function fetchTemplateData($templateId, $params)
    {
        try {
            // 根据模板ID选择数据源
            switch ($templateId) {
                case 'welcome':
                    return self::getWelcomeData($params);
                case 'code':
                    return self::getCodeData($params);
                case 'register':
                    return self::getRegisterData($params['to']);
                case 'cart':
                    return self::getCartData($params);
                case 'order_partial_payment':
                    return self::getOrderPartialPaymentData($params);
                case 'order_payment':
                    return self::getOrderPaymentData($params);
                case 'order_shipped':
                    return self::getOrderShippedData($params);
                case 'order_success':
                    return self::getOrderSuccessData($params);
                case 'self_pickup':
                    return self::getSelfPickupData($params);
                case 'coupon':
                    return self::getCouponData($params);
                case 'order_refund':
                    return self::getOrderRefundData($params);
                case 'order_cancel_timeout':
                    return self::getOrderCancelTimeoutData($params);
                case 'order_cancel_price_change':
                    return self::getOrderCancelPriceChange($params);
                default:
                    return [];
            }
        } catch (\Exception $e) {
            Log::error("Template data error: " . $e->getMessage() . ' ' . $e->getFile() . ' ' . $e->getLine());
            return false;
        }
    }


    /**
     * 返回邮件模板替换数据
     * 返回格式：[模板变量1=>实际值1,模板变量2=>实际值2]
     * @param $params
     * @return array
     */
    private static function getRegisterData($params): array
    {
        $user_name = explode('@', $params);
        return $replacements = [
            '{{user_name}}' => $user_name[0] ?? ''

        ];
    }

    /**
     * 返回邮件模板替换数据
     * 返回格式：[模板变量1=>实际值1,模板变量2=>实际值2]
     * @param $params
     * @return array
     */
    private static function getCodeData($params): array
    {
        $user_name = explode('@', $params['to']);
        return $replacements = [
            '{{user_name}}' => $user_name[0] ?? '',
            '{{code}}' => $params['code'] ?? '',

        ];
    }
    /**
     * 加购 24  48 小时发邮件
     * 返回格式：[模板变量1=>实际值1,模板变量2=>实际值2]
     * @param $params
     * @return array
     */
    private static function getCartData($params): array
    {

        return $replacements = [
            '{{user_name}}' => $params['user_name'] ?? '',
            '{{products}}' => $params['products'] ?? '',
            '{{cart_url}}' => $params['cart_url'] ?? '',

        ];
    }
    /**

     * 创建优惠券发邮件
     * 返回格式：[模板变量1=>实际值1,模板变量2=>实际值2]
     * @param $params
     * @return array
     */
    private static function getCouponData($params): array
    {

        return $replacements = [
            '{{user_name}}' => $params['user_name'] ?? '',
            '{{code_title}}' => $params['code_title'] ?? '',
            '{{discount_value}}' => $params['discount_value'] ?? '',

        ];
    }

    /**
     * @describe 订单支付邮件
     * @author: Bobo
     * @date: 2025-05-30 15:40:17 
     * @param [type] @required
     * @return Renderable
     */
    private static function getOrderPaymentData($params): array
    {
        return [
            '{{user_name}}' => $params['user_info']['cusname'] ?? '',
            '{{order_items}}' => $params['order_info']['list'] ?? [],
            '{{order_info}}' => $params['order_info'] ?? [], // 添加完整的order_info对象支持嵌套访问
        ];
    }
    /**
     * @describe 订单部分支付邮件
     * @author: Bobo
     * @date: 2025-05-30 15:40:17 
     * @param [type] @required
     * @return Renderable
     */

    private static function getOrderPartialPaymentData($params): array
    {


        $totalAmount = $params['order_info']['total_amount'] ?? 0;
        $payAmount = $params['order_info']['pay_amount'] ?? 0;
        $totalNeedPaid = $totalAmount - $payAmount;
        return [
            '{{user_name}}' => $params['user_info']['cusname'] ?? '',
            '{{order_items}}' => $params['order_info']['list'] ?? [],
            '{{total_need_paid}}' => $totalNeedPaid,
            '{{order_info}}' => $params['order_info'] ?? [], // 添加完整的order_info对象支持嵌套访问
        ];
    }

    private static function getOrderShippedData($params): array
    {
        return [
            '{{user_name}}' => $params['user_name'] ?? '',
            '{{order_info}}' => $params['order_info'] ?? [],
            '{{shipped_items}}' => $params['logistics_product_items'] ?? [],
            '{{logistics}}' => $params['logistics'] ?? '',
        ];
    }

    private static function getOrderSuccessData($params): array
    {
        $totalAmount = $params['order_info']['total_amount'] ?? 0;
        return [
            '{{order_no}}' => $params['order_info']['order_no'] ?? '',
            '{{user_name}}' => $params['user_info']['cusname'] ?? '',
            '{{order_items}}' => $params['order_info']['list'] ?? [],
            '{{product_total_amount}}' => $params['order_info']['product_total_amount'] ?? '',
            '{{total_amount}}' => $totalAmount,
            '{{logistics_fee}}' => $params['order_info']['logistics_fee'] ?? '',
            '{{order_info}}' => $params['order_info'] ?? [], // 添加完整的order_info对象支持嵌套访问
        ];
    }

    private static function getOrderRefundData($params): array
    {
        return [
            '{{user_name}}' => $params['user_name'] ?? '',
            '{{order_info}}' => $params['order_info'] ?? [],
            '{{returnorder_paid_amount}}' => $params['returnorder_paid_amount'] ?? '',
        ];
    }

    private static function getOrderCancelTimeoutData($params): array
    {
        return [
            '{{user_name}}' => $params['user_name'] ?? '',
            '{{order_info}}' => $params['order_info'] ?? [],
        ];
    }

    private static function getOrderCancelPriceChange($params): array
    {
        return [
            '{{user_name}}' => $params['user_name'] ?? '',
            '{{order_info}}' => $params['order_info'] ?? [],
        ];
    }


    private static function getSelfPickupData($params): array
    {
        $totalAmount = $params['order_info']['total_amount'] ?? 0;
        return [
            '{{order_no}}' => $params['order_info']['order_no'] ?? '',
            '{{products}}' => $params['products'] ?? '',
            '{{pickup_address}}' => $params['pickup_address'] ?? '',
            '{{user_name}}' => $params['user_info']['cusname'] ?? '',
            '{{order_items}}' => $params['order_info']['list'] ?? [],
            '{{product_total_amount}}' => $params['order_info']['product_total_amount'] ?? '',
            '{{total_amount}}' => $totalAmount,
            '{{logistics_fee}}' => $params['order_info']['logistics_fee'] ?? '',
            '{{order_info}}' => $params['order_info'] ?? [], // 添加完整的order_info对象支持嵌套访问
        ];
    }
    private static function renderTemplate($templateContent, $templateData)
    {
        // 处理循环结构
        $templateContent = self::processLoops($templateContent, $templateData);

        // 处理条件语句
        $templateContent = self::processConditions($templateContent, $templateData);

        // 处理对象属性访问，支持多层嵌套如 {{order_info.shipping_address.first_name}}
        $templateContent = self::processObjectAccess($templateContent, $templateData);

        // 处理简单的变量替换
        foreach ($templateData as $key => $value) {
            if (!is_array($value) && is_string($key)) {
                // 确保key和value都是有效的类型
                $safeValue = is_null($value) ? '' : (string)$value;
                $templateContent = str_replace($key, $safeValue, $templateContent);
            }
        }

        return $templateContent;
    }


    private static function processLoops($templateContent, $templateData)
    {
        // 匹配循环语法: {% for item in order_items %}...{% endfor %} 或 {% for item in order_info.list %}...{% endfor %}
        $pattern = '/\{%\s*for\s+(\w+)\s+in\s+([\w\.]+)\s*%\}(.*?)\{%\s*endfor\s*%\}/s';

        return preg_replace_callback($pattern, function ($matches) use ($templateData) {
            $itemVar = $matches[1]; // item
            $arrayPath = $matches[2]; // order_items 或 order_info.list
            $loopTemplate = $matches[3]; // 循环内容

            // 解析数组路径
            $arrayData = null;
            if (strpos($arrayPath, '.') !== false) {
                // 处理嵌套路径，如 order_info.list
                $pathParts = explode('.', $arrayPath);
                $rootObjectName = $pathParts[0];
                $rootObjectKey = '{{' . $rootObjectName . '}}';

                if (isset($templateData[$rootObjectKey]) && is_array($templateData[$rootObjectKey])) {
                    $currentData = $templateData[$rootObjectKey];
                    // 逐层访问嵌套属性
                    for ($i = 1; $i < count($pathParts); $i++) {
                        if (is_array($currentData) && array_key_exists($pathParts[$i], $currentData)) {
                            $currentData = $currentData[$pathParts[$i]];
                        } else {
                            $currentData = null;
                            break;
                        }
                    }
                    $arrayData = $currentData;
                }
            } else {
                // 处理简单路径，如 order_items
                $arrayKey = '{{' . $arrayPath . '}}';
                $arrayData = $templateData[$arrayKey] ?? null;
            }

            // 检查数组数据是否有效
            if (!is_array($arrayData)) {
                return ''; // 如果没有找到数组数据，返回空字符串
            }

            $result = '';
            foreach ($arrayData as $item) {
                // 确保item是数组
                if (!is_array($item)) {
                    continue;
                }

                $itemContent = $loopTemplate;
                // 替换循环内的变量，如 {{item.product_name}}
                foreach ($item as $field => $value) {
                    // 确保field是字符串，value不是null
                    if (!is_string($field)) {
                        continue;
                    }
                    $safeValue = is_null($value) ? '' : (string)$value;
                    $itemContent = str_replace('{{' . $itemVar . '.' . $field . '}}', $safeValue, $itemContent);
                }
                $result .= $itemContent;
            }

            return $result;
        }, $templateContent);
    }

    private static function processConditions($templateContent, $templateData)
    {
        $hasChanges = true;
        $iterations = 0;

        // 循环处理直到没有更多条件需要处理，防止无限循环
        while ($hasChanges && $iterations < 10) {
            $originalContent = $templateContent;
            $iterations++;

            // 处理最内层的if-else结构（不包含嵌套的if）
            $simpleIfElsePattern = '/\{%\s*if\s+([^%]+?)\s*%\}((?:(?!\{%\s*if\s).)*?)\{%\s*else\s*%\}((?:(?!\{%\s*if\s).)*?)\{%\s*endif\s*%\}/s';
            $templateContent = preg_replace_callback($simpleIfElsePattern, function ($matches) use ($templateData) {
                $condition = trim($matches[1]);
                $ifContent = $matches[2];
                $elseContent = $matches[3];

                if (self::evaluateCondition($condition, $templateData)) {
                    return $ifContent;
                } else {
                    return $elseContent;
                }
            }, $templateContent);

            // 处理最内层的单独if结构（不包含嵌套的if和else）
            $simpleIfPattern = '/\{%\s*if\s+([^%]+?)\s*%\}((?:(?!\{%\s*(?:if|else)\s).)*?)\{%\s*endif\s*%\}/s';
            $templateContent = preg_replace_callback($simpleIfPattern, function ($matches) use ($templateData) {
                $condition = trim($matches[1]);
                $ifContent = $matches[2];

                if (self::evaluateCondition($condition, $templateData)) {
                    return $ifContent;
                } else {
                    return '';
                }
            }, $templateContent);

            // 检查是否还有变化
            $hasChanges = ($originalContent !== $templateContent);
        }

        return $templateContent;
    }

    private static function evaluateCondition($condition, $templateData)
    {
        // 添加调试信息

        // 支持等于比较: object.property == 'value' 或 object.property == value
        if (preg_match('/^(\w+(?:\.\w+)*)\s*==\s*[\'"]([^\'"]*)[\'"]$/', $condition, $matches)) {
            // 字符串比较
            $propertyPath = $matches[1];
            $expectedValue = $matches[2];
            $actualValue = self::getNestedValue($propertyPath, $templateData);

            return $actualValue === $expectedValue;
        }

        if (preg_match('/^(\w+(?:\.\w+)*)\s*==\s*(\d+)$/', $condition, $matches)) {
            // 数字比较
            $propertyPath = $matches[1];
            $expectedValue = $matches[2];
            $actualValue = self::getNestedValue($propertyPath, $templateData);

            return $actualValue == $expectedValue; // 使用 == 进行类型转换比较
        }

        // 支持不等于比较: object.property != 'value' 或 object.property != value
        if (preg_match('/^(\w+(?:\.\w+)*)\s*!=\s*[\'"]([^\'"]*)[\'"]$/', $condition, $matches)) {
            $propertyPath = $matches[1];
            $expectedValue = $matches[2];
            $actualValue = self::getNestedValue($propertyPath, $templateData);
            return $actualValue !== $expectedValue;
        }

        if (preg_match('/^(\w+(?:\.\w+)*)\s*!=\s*(\d+)$/', $condition, $matches)) {
            $propertyPath = $matches[1];
            $expectedValue = $matches[2];
            $actualValue = self::getNestedValue($propertyPath, $templateData);
            return $actualValue != $expectedValue;
        }

        // 支持存在检查: object.property
        if (preg_match('/^(\w+(?:\.\w+)*)$/', $condition, $matches)) {
            $propertyPath = $matches[1];
            $actualValue = self::getNestedValue($propertyPath, $templateData);
            return !empty($actualValue);
        }

        return false; // 无法解析的条件，默认为false
    }

    private static function getNestedValue($propertyPath, $templateData)
    {
        $pathParts = explode('.', $propertyPath);
        $rootObjectName = $pathParts[0];
        $rootObjectKey = '{{' . $rootObjectName . '}}';

        if (!isset($templateData[$rootObjectKey]) || !is_array($templateData[$rootObjectKey])) {
            return null;
        }

        $currentData = $templateData[$rootObjectKey];
        for ($i = 1; $i < count($pathParts); $i++) {
            if (!is_array($currentData) || !array_key_exists($pathParts[$i], $currentData)) {
                return null;
            }
            $currentData = $currentData[$pathParts[$i]];
        }

        return $currentData;
    }

    private static function processObjectAccess($templateContent, $templateData)
    {
        // 匹配对象属性访问语法，支持多层嵌套: {{object.property.subproperty}}
        $pattern = '/\{\{(\w+(?:\.\w+)+)\}\}/';

        return preg_replace_callback($pattern, function ($matches) use ($templateData) {
            $propertyPath = $matches[1]; // order_info.state
            $pathParts = explode('.', $propertyPath);

            // 第一层必须是已定义的对象
            $rootObjectName = $pathParts[0];
            $rootObjectKey = '{{' . $rootObjectName . '}}';

            if (!isset($templateData[$rootObjectKey]) || !is_array($templateData[$rootObjectKey])) {
                return $matches[0]; // 如果没有找到根对象数据，返回原始字符串
            }

            // 从根对象开始，逐层访问属性
            $currentData = $templateData[$rootObjectKey];
            for ($i = 1; $i < count($pathParts); $i++) {
                if (!is_array($currentData) || !array_key_exists($pathParts[$i], $currentData)) {
                    return $matches[0]; // 如果路径不存在，返回原始字符串
                }
                $currentData = $currentData[$pathParts[$i]];
            }

            // 确保value不是null，避免PHP 8.1+的废弃警告
            // 注意：这里不使用?? ''，因为空字符串也是有效值
            return is_null($currentData) ? '' : (string)$currentData;
        }, $templateContent);
    }

    /**
     * 欢迎邮件数据
     * @param $params
     * @return array
     */
    private static function getWelcomeData($params): array
    {
        return [
            '{{user_name}}' => $params['user_name'] ?? '',
        ];
    }
}
